package com.yingdong.db.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.locks.ReentrantLock;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class DBManager {
	static Logger logger = LoggerFactory.getLogger(DBManager.class);
	private static ComboPooledDataSource ds;
	private static ReentrantLock lock = new ReentrantLock();

	public static void init() throws Exception {
		Properties prop = new Properties();
		File f = new File("conf/mybatis.properties");
		InputStream in = new FileInputStream(f);
		prop.load(in);
		ds = new ComboPooledDataSource("dataSource");
		ds.setDriverClass(prop.getProperty("db.driver"));
		ds.setJdbcUrl(prop.getProperty("db.url"));
		ds.setUser(prop.getProperty("db.username"));
		ds.setPassword(prop.getProperty("db.password"));
		ds.setPreferredTestQuery(prop.getProperty("db.preferredTestQuery"));
		ds.setMaxPoolSize(50);
		ds.setMaxIdleTime(300);
	}

	public static ComboPooledDataSource getDs() {
		return ds;
	}

	public static void setDs(ComboPooledDataSource ds) {
		DBManager.ds = ds;
	}

	public static Connection getConnection() throws SQLException {

		try {
			lock.lock();
			Connection conn = ds.getConnection();
			return conn;
		} finally {

			lock.unlock();
		}
	}

	public static void closeConnection(Connection conn) {

		if (conn != null) {
			try {
				lock.lock();
				conn.close();
			} catch (SQLException e) {

				logger.error("", e);
			} finally {
				lock.unlock();
			}

		}
	}

	public static void closeConnection(Connection conn, PreparedStatement preparedStatement) {

		closeConnection(conn);
		if (preparedStatement != null) {
			try {
				preparedStatement.close();
			} catch (SQLException e) {
				logger.error("", e);
			} finally {

			}
		}
	}

	public static void closeConnection(Connection conn, PreparedStatement preparedStatement, ResultSet rs) {

		closeConnection(conn, preparedStatement);
		if (rs != null) {
			try {
				rs.close();
			} catch (SQLException e) {
				logger.error("", e);
			} finally {

			}
		}
	}

	public static void prepareStatementSet(PreparedStatement preparedStatement, DBParamWrapper dbParamWrapper) throws SQLException {
		if (dbParamWrapper != null) {
			for (int i = 0; i < dbParamWrapper.getParamList().size(); i++) {
				if ((int) dbParamWrapper.getParamList().get(i)[0] == Types.JAVA_OBJECT)
					preparedStatement.setObject(i + 1, dbParamWrapper.getParamList().get(i)[1]);
				else
					preparedStatement.setObject(i + 1, dbParamWrapper.getParamList().get(i)[1], (int) dbParamWrapper.getParamList().get(i)[0]);
			}
		}
	}

	public static void prepareStatementBatchSet(PreparedStatement preparedStatement, List<DBParamWrapper> dbParamWrappers) throws SQLException {
		if (dbParamWrappers != null) {
			for (DBParamWrapper dbParamWrapper : dbParamWrappers) {
				for (int i = 0; i < dbParamWrapper.getParamList().size(); i++) {
					if (dbParamWrapper.getParamList().get(i)[1] != null)
						preparedStatement.setObject(i + 1, dbParamWrapper.getParamList().get(i)[1], (int) dbParamWrapper.getParamList().get(i)[0]);
					else
						preparedStatement.setNull(i + 1, (int) dbParamWrapper.getParamList().get(i)[0]);
				}
				preparedStatement.addBatch();
			}
		}
	}

}
